package com.sun.springbootspi.controller;

import com.sun.springbootspi.service.Logger;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.ServiceLoader;

/**
 * @version 1.0
 * @Package: com.sun.springbootspi.controller
 * @ClassName: LoggerController
 * @Author: sgq
 * @Date: 2025/1/1 18:27
 * @Description: TODD
 */

/**
 * 在上述示例中：
 * 首先定义了一个通用的 Logger 接口，用于抽象日志记录的行为。
 * 然后创建了两个具体的实现类 ConsoleLogger 和 FileLogger，分别将日志输出到控制台和文件中。
 * 通过 SPI 机制，在 resources/META-INF/cs 目录下配置了 Logger 接口的实现类列表。
 * 在 Spring Boot 应用中，使用 ServiceLoader 加载所有的 Logger 实现，并将它们作为 Logger 数组类型的 bean 注入到 Spring 容器中。
 * 最后在 LoggerController 中，通过注入的 Logger 数组，对所有的日志记录器进行调用，实现了日志记录的动态扩展。如果后续需要添加新的日志记录方式，例如将日志发送到远程服务器，只需要创建一个新的 Logger 接口实现类，并在 SPI 配置文件中添加相应的类名，Spring Boot 应用就能够自动加载并使用这个新的日志记录器，无需修改原有的代码逻辑，充分体现了 SPI 的灵活性和可扩展性，这也是其精髓所在。
 * 请注意，上述示例中的文件日志记录器只是简单地将日志追加到文件中，没有考虑日志的格式、滚动等复杂的文件日志管理功能，在实际应用中，你可能需要使用更成熟的日志框架来处理这些问题。同时，异常处理也可以进一步优化，这里为了简洁明了，只进行了简单的打印堆栈信息。
 */
@RestController
@Slf4j
@AllArgsConstructor
public class LoggerController {
    @Autowired
    private final Logger[] loggers;

//    public LoggerController(List<Logger> loggers) {
//        this.loggers = loggers.toArray(new Logger[0]);
//        System.out.println("成功注入Logger实现类，数量为： " + loggers.size());
//    }

    @GetMapping("/log")
    public String logMessage() {
        String message = "这是一条测试日志";
        for (Logger logger : loggers) {
            logger.log(message);
        }
        return "日志记录成功";
    }
}